/**
 * スケッチシステムを使う場合の実装
 */
#include "boot/sketch.h"
#include "NyLPC_uipService.h"
//イーサネット用の初期化情報
const struct NyLPC_TEthAddr ethaddr=NyLPC_TEthAddr_pack(0x00,0x01,0x02,0x03,0x04,0x05);
const struct NyLPC_TIPv4Addr ipaddr=NyLPC_TIPv4Addr_pack(192,168,128,201);
const struct NyLPC_TIPv4Addr netmask=NyLPC_TIPv4Addr_pack(255,255,255,0);
const struct NyLPC_TIPv4Addr gateway=NyLPC_TIPv4Addr_pack(192,168,128,254);
char sockbuf[1500];
char workbuf[1500];

void setup(void)
{
	int i;
	//uipサービス初期化。いろいろ利用可能に。
	NyLPC_cUipService_initialize();
	for(i=0;i<512;i++){
		sockbuf[i]='A';
		workbuf[i]='A';
	}
}




void recv_loop(void)
{
	NyLPC_TcIPv4Config_t config;
	NyLPC_TcTcpListener_t listener;
	NyLPC_TcTcpSocket_t socket;
	const char *buf;
	NyLPC_TInt32 s,stotal;



	NyLPC_cIPv4Config_initialzeForEthernet(&config,&ethaddr,1480);
	NyLPC_cIPv4Config_setDefaultRoute(&config,&gateway);
	NyLPC_cIPv4Config_setIp(&config,&ipaddr,&netmask);


	NyLPC_cTcpListener_initialize(&listener,23);
	NyLPC_cTcpSocket_initialize(&socket,sockbuf,512);
	NyLPC_cUipService_start(&config);
	for(;;){
		//リスニング
		if(!NyLPC_cTcpListener_listen(&listener,&socket,10000)){
			continue;
		}
		//Accept
		if(!NyLPC_cTcpSocket_accept(&socket,10000)){
			NyLPC_cTcpSocket_close(&socket,10000);
			continue;
		}
		//接続中は送信する。
		stotal=0;
		s=NyLPC_cTcpSocket_precv(&socket,(const void**)&buf,1000);
		while(s>=0){
			NyLPC_cTcpSocket_pseek(&socket,s);
			stotal+=s;
			if(stotal>=1024*1024){
				break;
			}
			s=NyLPC_cTcpSocket_precv(&socket,(const void**)&buf,1000);
		}
		NyLPC_cTcpSocket_close(&socket,10000);
	}
}

/**
 * コネクションに対して、10MBのデータを送信し、コネクションを切断します。
 */
void send_loop(void)
{
	NyLPC_TcIPv4Config_t config;
	NyLPC_TcTcpListener_t listener;
	NyLPC_TcTcpSocket_t socket;
	const char *rp;
	NyLPC_TInt32 s,r,stotal;



	NyLPC_cIPv4Config_initialzeForEthernet(&config,&ethaddr,1480);
	NyLPC_cIPv4Config_setDefaultRoute(&config,&gateway);
	NyLPC_cIPv4Config_setIp(&config,&ipaddr,&netmask);


	NyLPC_cTcpListener_initialize(&listener,23);
	NyLPC_cTcpSocket_initialize(&socket,sockbuf,512);
	NyLPC_cUipService_start(&config);
	for(;;){
		//リスニング
		if(!NyLPC_cTcpListener_listen(&listener,&socket,10000)){
			continue;
		}
		//Accept
		if(!NyLPC_cTcpSocket_accept(&socket,10000)){
			NyLPC_cTcpSocket_close(&socket,10000);
			continue;
		}
		//接続中は送信する。
		stotal=0;
		s=NyLPC_cTcpSocket_send(&socket,sockbuf,1024,30000);
		while(s>=0){
			stotal+=s;
			s=NyLPC_cTcpSocket_send(&socket,sockbuf,1024,30000);
			if(stotal>=10*1024*1024){
				break;
			}
		}
		NyLPC_cTcpSocket_close(&socket,10000);
	}
}



void loopback(void)
{
	NyLPC_TcIPv4Config_t config;
	NyLPC_TcTcpListener_t listener;
	NyLPC_TcTcpSocket_t socket;
	const char *buf;
	NyLPC_TInt32 s,stotal;



	NyLPC_cIPv4Config_initialzeForEthernet(&config,&ethaddr,1480);
	NyLPC_cIPv4Config_setDefaultRoute(&config,&gateway);
	NyLPC_cIPv4Config_setIp(&config,&ipaddr,&netmask);


	NyLPC_cTcpListener_initialize(&listener,23);
	NyLPC_cTcpSocket_initialize(&socket,sockbuf,1024);
	NyLPC_cUipService_start(&config);
	for(;;){
		//リスニング
		if(!NyLPC_cTcpListener_listen(&listener,&socket,10000)){
			continue;
		}
		//Accept
		if(!NyLPC_cTcpSocket_accept(&socket,10000)){
			NyLPC_cTcpSocket_close(&socket,10000);
			continue;
		}
		//接続中は送信する。
		s=NyLPC_cTcpSocket_precv(&socket,(const void**)&buf,1000);
		while(s>=0){
			//memcpy(workbuf,buf,s);
			if(s>0){
				NyLPC_cTcpSocket_pseek(&socket,s);
				NyLPC_cTcpSocket_send(&socket,workbuf,s,30000);
			}
			s=NyLPC_cTcpSocket_precv(&socket,(const void**)&buf,1000);
		}
		NyLPC_cTcpSocket_close(&socket,10000);
	}
}




void loop(void)
{
	loopback();
//	recv_loop();
//	send_loop();
	for(;;){}
}
